package org.example.electronic_fence.controller;

import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.example.electronic_fence.model.BaseModel;
import org.example.electronic_fence.model.ElectronicFence;
import org.example.electronic_fence.model.HWDS;
import org.example.electronic_fence.model.VirtualSensors;
import org.example.electronic_fence.model.dto.ControlParam;
import org.example.electronic_fence.model.dto.DeviceControlDto;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

@RestController
public class EfController {
    private final ObjectMapper objectMapper = new ObjectMapper();
    @Autowired
    private VirtualSensors virtualSensors;

    @PostMapping("/update")
    public String update(@RequestBody ElectronicFence baseModel) throws JsonProcessingException, NoSuchFieldException, IllegalAccessException {
        Map<String, BaseModel> allVirtualSensors = virtualSensors.getAllVirtualSensors();
        String key=virtualSensors.getPrimaryKey((BaseModel) baseModel);
        if(baseModel.getFenceAlarm()==null) {
            BaseModel model = new BaseModel();
            BeanUtils.copyProperties(baseModel, model);
            allVirtualSensors.put(key, model);
        }
        else allVirtualSensors.put(key,baseModel);
        return "修改成功";
    }

    @GetMapping("getAllInfo")
    public String getAllInfo() throws JsonProcessingException {
        Map<String, BaseModel> allVirtualSensors = virtualSensors.getAllVirtualSensors();
        List<Object> ret = new ArrayList<>();
        allVirtualSensors.forEach((key, value) -> {
            if (value instanceof ElectronicFence) {
                ret.add((ElectronicFence) value);  // 转成ElectronicFence
            } else if (value instanceof HWDS) {
                ret.add((HWDS) value);  // 转成HWDS
            } else {
                ret.add(value);
            }
        });
        return JSON.toJSONString(ret);
    }

    @PostMapping("/addDevice")
    public String addDevice(@RequestBody Map<String, Object> payload) throws JsonProcessingException {
        Map<String, BaseModel> allVirtualSensors = virtualSensors.getAllVirtualSensors();

        String type = (String) payload.get("type");
        String d_id = (String) payload.get("d_id");
        Integer devNO = payload.get("devNO") != null ? (Integer) payload.get("devNO") : null;
        Integer zoneNO = payload.get("zoneNO") != null ? (Integer) payload.get("zoneNO") : null;

        BaseModel baseModel;

        if ("ef".equalsIgnoreCase(type)) {
            if (virtualSensors.countEf() >= 8) return "电子围栏设备数量已达上限（8个）";
            ElectronicFence ef = new ElectronicFence();
            ef.setFenceAlarm(0);
            ef.setFenceSlack(0);
            ef.setFenceCut(0);
            ef.setFenceDcVal(100);
            baseModel = ef;
        } else if ("hwds".equalsIgnoreCase(type)) {
            if (virtualSensors.countHwds() >= 1) return "红外对射设备数量已达上限（1个）";
            baseModel = new HWDS();
        } else {
            return "设备类型错误";
        }

        baseModel.setD_id(d_id);
        baseModel.setDevNO(devNO);
        baseModel.setZoneNO(zoneNO);

        String key = virtualSensors.getPrimaryKey(baseModel);
        allVirtualSensors.put(key, baseModel);

        return "添加成功";
    }


    @PostMapping("/deleteDevice")
    public String deleteDevice(@RequestBody BaseModel baseModel) throws JsonProcessingException {
        Map<String, BaseModel> allVirtualSensors = virtualSensors.getAllVirtualSensors();
        String key = virtualSensors.getPrimaryKey(baseModel);
        if (allVirtualSensors.remove(key) != null) {
            return "删除成功";
        } else {
            return "设备不存在";
        }
    }



    /*-------------------以上接口是提供给我们自己使用，方便用来快修模拟数据,一遍平台能够接受改变的数据，用来测试-------------*/

    /**-------------------------------------------一下接口是提供给平台使用---------------------**/

    /**
     * 获取警情信息
     * @return
     */
    @PostMapping("/GetAlarm")
    public String getAlarm() {
        try {
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String eventDate = now.format(formatter);
//            String eventDate ="2025-04-27 16:00:00";

            // 创建根节点
            ObjectNode root = objectMapper.createObjectNode();
            root.put("ErrNO", 0);
            root.put("DataType", 1);

            // 创建数据数组
            ArrayNode dataArray = objectMapper.createArrayNode();

            // 遍历所有虚拟传感器
            virtualSensors.getAllVirtualSensors().forEach((key, value) -> {
                // 添加报警信息
                addEvent(dataArray, value, eventDate, "Alarm", value.getAlarm());
                // 添加布撤防信息
                addEvent(dataArray, value, eventDate, "Arm", value.getArm());
                // 添加设备在线状态信息
                addEvent(dataArray, value, eventDate, "DevOnline", value.getDevOnline());
                // 添加设备被撬状态信息
                addEvent(dataArray, value, eventDate, "DevTamper", value.getDevTamper());
                // 添加设备欠压状态信息
                addEvent(dataArray, value, eventDate, "DevDcLow", value.getDevDcLow());
                // 添加交流断电状态信息
                addEvent(dataArray, value, eventDate, "DevAcLoss", value.getDevAcLoss());
                // 添加围栏防区报警状态信息
                // 如果是电子围栏，添加额外的事件
                if (value instanceof ElectronicFence) {
                    addEvent(dataArray, value, eventDate, "FenceAlarm", ((ElectronicFence) value).getFenceAlarm());
                    addEvent(dataArray, value, eventDate, "FenceSlack", ((ElectronicFence) value).getFenceSlack());
                    addEvent(dataArray, value, eventDate, "FenceCut", ((ElectronicFence) value).getFenceCut());
                    addEvent(dataArray, value, eventDate, "FenceDcVal", ((ElectronicFence) value).getFenceDcVal());
                }
            });

            // 将数据数组添加到根节点
            root.set("Data", dataArray);

            // 返回 JSON 字符串
            String jsonStr = objectMapper.writeValueAsString(root);
            return jsonStr;
        } catch (Exception e) {
            e.printStackTrace();
            return "{\"ErrNO\": 1, \"DataType\": 1, \"Data\": []}";
        }
    }

    private void addEvent(ArrayNode dataArray, BaseModel value, String eventDate, String eventName, int eventVal) {
        ObjectNode eventData = objectMapper.createObjectNode();
        eventData.put("D_ID", value.getD_id());
        eventData.put("DevNO", 1);
        if (value instanceof ElectronicFence) {
            eventData.put("ZoneNO", value.getZoneNO());
        }
        eventData.put("EventName", eventName);
        eventData.put("EventType", 0);
        eventData.put("EventVal", eventVal);
        eventData.put("EventTime", eventDate);
        dataArray.add(eventData);
    }

    private int getRandomEventVal() {
        Random random = new Random();
        return random.nextInt(2); // 返回 0 或 1
    }

    /**
     * 控制设备
     */
    @PostMapping("/ControlDevice")
    public String controlDevice(@RequestBody ControlParam controlParam) throws JsonProcessingException, NoSuchFieldException, IllegalAccessException {
        // 创建根节点
        ObjectNode root = objectMapper.createObjectNode();
        if (controlParam.getDataType() != 2) {
            //非法操作
            root.put("ErrNO", 3);
            return objectMapper.writeValueAsString(root);
        }
        ;
        for (int i = 0; i < controlParam.getData().size(); i++) {
            DeviceControlDto deviceControlDto = controlParam.getData().get(i);
            String d_id = deviceControlDto.getD_ID();
            String commNO = null;
            if (deviceControlDto.getCommNO() != null)
                commNO = String.valueOf(deviceControlDto.getCommNO());
            Integer devNO = deviceControlDto.getDevNO();
            Integer zoneNO = deviceControlDto.getZoneNO();
            String primaryKey = virtualSensors.getPrimaryKey(d_id, commNO, devNO, zoneNO);
            BaseModel baseModel = virtualSensors.getVirtualSensor(primaryKey);
            if (deviceControlDto.getPwd() == null ||
                    !(deviceControlDto.getPwd().equals(virtualSensors.getPwd()))) {
                root.put("ErrNO", 3);
                return objectMapper.writeValueAsString(root);
            }
            String eventName = deviceControlDto.getEventName();
            Integer eventType = deviceControlDto.getEventType();
            Integer eventVal = deviceControlDto.getEventVal();
            if (eventName != null) {
                if (eventName.equals("OptArm")) {
                    //布撤防操作
                    eventName = "Arm";
                    if (eventVal == 0 || eventVal == 1)
                        updateData(baseModel, eventName, eventType, eventVal);
                    else if (eventVal == 2) {
                        //留守布防，什么意思不知道
                    } else if ((baseModel instanceof ElectronicFence) && eventVal == 3) {
                        //高压布防
                        ElectronicFence baseModel1 = (ElectronicFence) baseModel;
                        baseModel1.setFenceDcVal(100000);//默认高压
                    } else if ((baseModel instanceof ElectronicFence) && eventVal == 4) {
                        //低压布防
                        ElectronicFence baseModel1 = (ElectronicFence) baseModel;
                        baseModel1.setFenceDcVal(10);//默认低压
                    } else if (baseModel instanceof HWDS) {
                        //红外对射不知道有没有电压布防
                    }
                } else if (eventName.equals("FenceDcArm")) {
                    //圧值布防
                    eventName = "FenceDcVal";
                    updateData(baseModel, eventName, eventType, eventVal);
                }
            }
        }
        ;
        root.put("ErrNO", 0);
        return objectMapper.writeValueAsString(root);
    }

    private void updateData(BaseModel baseModel, String eventName, Integer eventType, Integer eventVal) throws NoSuchFieldException, IllegalAccessException {
        //将eventName改为驼峰
        String camelCaseName = eventName.substring(0, 1).toLowerCase() + eventName.substring(1);
        try {
            //拿到包括父类的字段
            Field declaredField = BaseModel.class.getDeclaredField(camelCaseName);
            declaredField.setAccessible(true);
            declaredField.set(baseModel, eventVal);
            return;
        } catch (NoSuchFieldException e) {
            if (baseModel instanceof ElectronicFence) {
                Field declaredField = ElectronicFence.class.getDeclaredField(camelCaseName);
                declaredField.setAccessible(true);
                declaredField.set(baseModel, eventVal);
            }
            if (baseModel instanceof HWDS) {
                Field declaredField = HWDS.class.getDeclaredField(camelCaseName);
                declaredField.setAccessible(true);
                declaredField.set(baseModel, eventVal);
            }
        }
        ;
        //使用反射遍历和eventName匹配的属性，并更新对应的值
    }
}